/**
 * Copyright (c) 2008, Andrew Carter
 * All rights reserved.
 * 
 * Redistribution and use in source and binary forms, with or without modification, are 
 * permitted provided that the following conditions are met:
 * 
 * Redistributions of source code must retain the above copyright notice, this list of 
 * conditions and the following disclaimer. Redistributions in binary form must reproduce 
 * the above copyright notice, this list of conditions and the following disclaimer in 
 * the documentation and/or other materials provided with the distribution. Neither the 
 * name of Andrew Carter nor the names of contributors may be used to endorse or promote 
 * products derived from this software without specific prior written permission. 
 * 
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY 
 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT 
 * SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT 
 * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR 
 * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */
package com.acarter.scenemonitor.propertydescriptor.editor;

import java.awt.Dimension;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseMotionListener;

import javax.swing.Box;
import javax.swing.BoxLayout;
import javax.swing.JButton;
import javax.swing.JDialog;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextField;

import com.jme.renderer.ColorRGBA;

/**
 * 
 * @author Andrew Carter
 */
public class ColorRGBAEditorPanel extends A_EditorPanel {

	/**	 */
	private static final long serialVersionUID = 1L;
	
	/**  */
	private JDialog dialog = null;
	
	/**  */
	private ColorRGBA color;
	
	/**  */
	private ColorRGBA cRestore;

	/**  */
	private JTextField componentR;

	/**  */
	private JTextField componentG;

	/**  */
	private JTextField componentB;

	/**  */
	private JTextField componentA;

	/**  */
	private JButton rSlider;

	/**  */
	private JButton gSlider;

	/**  */
	private JButton bSlider;

	/**  */
	private JButton aSlider;
	
	/**  */
	private JButton cancel;
	
	/**  */
	private JButton done;
	
	/**  */
	private int width = -1;

	/**
	 * 
	 * @param label 
	 * @param color 
	 * @param state
	 */
	public ColorRGBAEditorPanel(JDialog dialog, ColorRGBA color) {

		this.dialog = dialog;
		this.color = color;
		
		cRestore = new ColorRGBA(color);
		
		build();
		initValues();
	}

	/**
	 * 
	 * @param label 
	 * @param color 
	 * @param width 
	 * @param state
	 */
	public ColorRGBAEditorPanel(JDialog dialog, ColorRGBA color, int width) {

		this.dialog = dialog;
		this.color = color;
		this.width = width;
		
		cRestore = new ColorRGBA(color);
		
		build();
		initValues();
	}

	/**
	 * 
	 *
	 */
	private void build() {
		
		JLabel labelR = new JLabel("R: ");
		labelR.setFont(font);

		componentR = new JTextField();
		componentR.setFont(font);
		componentR.setPreferredSize(fieldDim);
		componentR.setMaximumSize(componentR.getPreferredSize());

		rSlider = new JButton();
		rSlider.setPreferredSize(sliderDim);
		rSlider.setMaximumSize(rSlider.getPreferredSize());
		rSlider.setToolTipText(sliderTooltip);

		JLabel labelG = new JLabel("G: ");
		labelG.setFont(font);

		componentG = new JTextField();
		componentG.setFont(font);
		componentG.setPreferredSize(fieldDim);
		componentG.setMaximumSize(componentG.getPreferredSize());

		gSlider = new JButton();
		gSlider.setPreferredSize(sliderDim);
		gSlider.setMaximumSize(gSlider.getPreferredSize());
		gSlider.setToolTipText(sliderTooltip);

		JLabel labelB = new JLabel("B: ");
		labelB.setFont(font);

		componentB = new JTextField();
		componentB.setFont(font);
		componentB.setPreferredSize(fieldDim);
		componentB.setMaximumSize(componentB.getPreferredSize());

		bSlider = new JButton();
		bSlider.setPreferredSize(sliderDim);
		bSlider.setMaximumSize(bSlider.getPreferredSize());
		bSlider.setToolTipText(sliderTooltip);

		JLabel labelA = new JLabel("A: ");
		labelA.setFont(font);

		componentA = new JTextField();
		componentA.setFont(font);
		componentA.setPreferredSize(fieldDim);
		componentA.setMaximumSize(componentA.getPreferredSize());

		aSlider = new JButton();
		aSlider.setPreferredSize(sliderDim);
		aSlider.setMaximumSize(aSlider.getPreferredSize());
		aSlider.setToolTipText(sliderTooltip);

		done = new JButton("Done");
		done.setFont(font);
		done.setPreferredSize(new Dimension(42, 15));
		done.setMaximumSize(done.getPreferredSize());
		done.setMargin(insets);

		cancel = new JButton("Cancel");
		cancel.setFont(font);
		cancel.setPreferredSize(new Dimension(42, 15));
		cancel.setMaximumSize(cancel.getPreferredSize());
		cancel.setMargin(insets);

		JPanel buttonPanel = new JPanel();
		buttonPanel.setLayout(new BoxLayout(buttonPanel, BoxLayout.X_AXIS));
		buttonPanel.add(done);
		buttonPanel.add(Box.createRigidArea(new Dimension(5, 0)));
		buttonPanel.add(cancel);
		buttonPanel.add(Box.createRigidArea(new Dimension(1, 0)));

		JPanel buttonPanel2 = new JPanel();
		buttonPanel2.setLayout(new BoxLayout(buttonPanel2, BoxLayout.Y_AXIS));
		buttonPanel2.add(Box.createGlue());
		buttonPanel2.add(buttonPanel);
		buttonPanel2.add(Box.createGlue());
		
		setLayout(new BoxLayout(this, BoxLayout.X_AXIS));
		
		if(width != -1) {
			add(Box.createRigidArea(new Dimension(width, 0)));
		}
		else {
			add(Box.createRigidArea(new Dimension(1, 0)));
			add(Box.createGlue());
		}
		
		add(labelR);
		add(componentR);
		add(rSlider);
		add(Box.createRigidArea(new Dimension(5, 0)));
		add(labelG);
		add(componentG);
		add(gSlider);
		add(Box.createRigidArea(new Dimension(5, 0)));
		add(labelB);
		add(componentB);
		add(bSlider);
		add(Box.createRigidArea(new Dimension(5, 0)));
		add(labelA);
		add(componentA);
		add(aSlider);
		add(Box.createRigidArea(new Dimension(5, 0)));
		add(buttonPanel2);
		
		if(width != -1)
			add(Box.createGlue());
		
		// listeners
		componentR.addActionListener(new ActionListener() {

			public void actionPerformed(ActionEvent evt) {
				onUpdate();
			}
		});
		
		componentR.addKeyListener(new KeyListener() {

			public void keyPressed(KeyEvent e) {
			}

			public void keyReleased(KeyEvent e) {
				onUpdate();
			}

			public void keyTyped(KeyEvent e) {
			}
			
		});
		
		rSlider.addMouseMotionListener(new MouseMotionListener() {

			public void mouseDragged(MouseEvent e) {
				
				color.r = slideValue(e, color.r, 1);
				
				initValues();
				
				if(callback != null)
					callback.componentModifiedCallback();
			}

			public void mouseMoved(MouseEvent e) {				
			}
		});

		componentG.addActionListener(new ActionListener() {

			public void actionPerformed(ActionEvent evt) {
				onUpdate();
			}
		});
		
		componentG.addKeyListener(new KeyListener() {

			public void keyPressed(KeyEvent e) {
			}

			public void keyReleased(KeyEvent e) {
				onUpdate();
			}

			public void keyTyped(KeyEvent e) {
			}
			
		});
		
		gSlider.addMouseMotionListener(new MouseMotionListener() {

			public void mouseDragged(MouseEvent e) {
				
				color.g = slideValue(e, color.g, 1);
				
				initValues();
				
				if(callback != null)
					callback.componentModifiedCallback();
			}

			public void mouseMoved(MouseEvent e) {
			}
		});

		componentB.addActionListener(new ActionListener() {

			public void actionPerformed(ActionEvent evt) {
				onUpdate();
			}
		});
		
		componentB.addKeyListener(new KeyListener() {

			public void keyPressed(KeyEvent e) {
			}

			public void keyReleased(KeyEvent e) {
				onUpdate();
			}

			public void keyTyped(KeyEvent e) {
			}
			
		});
		
		bSlider.addMouseMotionListener(new MouseMotionListener() {

			public void mouseDragged(MouseEvent e) {
				
				color.b = slideValue(e, color.b, 1);
				
				initValues();
				
				if(callback != null)
					callback.componentModifiedCallback();
			}

			public void mouseMoved(MouseEvent e) {
			}
		});

		componentA.addActionListener(new ActionListener() {

			public void actionPerformed(ActionEvent evt) {
				onUpdate();
			}
		});
		
		componentA.addKeyListener(new KeyListener() {

			public void keyPressed(KeyEvent e) {
			}

			public void keyReleased(KeyEvent e) {
				onUpdate();
			}

			public void keyTyped(KeyEvent e) {
			}
			
		});
		
		aSlider.addMouseMotionListener(new MouseMotionListener() {

			public void mouseDragged(MouseEvent e) {
				
				color.a = slideValue(e, color.a, 1);
				
				initValues();
				
				if(callback != null)
					callback.componentModifiedCallback();
			}

			public void mouseMoved(MouseEvent e) {
			}
		});

		done.addActionListener(new ActionListener() {

			public void actionPerformed(ActionEvent evt) {

				dialog.setVisible(false);
			}
		});

		cancel.addActionListener(new ActionListener() {

			public void actionPerformed(ActionEvent evt) {

				restoreValue();

				dialog.setVisible(false);
			}
		});
	}

	/**
	 * 
	 * 
	 */
	private void initValues() {

		componentR.setText(Float.toString(color.r));
		componentG.setText(Float.toString(color.g));
		componentB.setText(Float.toString(color.b));
		componentA.setText(Float.toString(color.a));
	}
	
	/**
	 * 
	 */
	public void restoreValue() {
		
		color.set(cRestore);
		
		if(callback != null)
			callback.componentModifiedCallback();
	}
	
	/**
	 * 
	 * @param callback
	 */
	public void setCallback(I_ComponentModificationCallback callback) {
		
		this.callback = callback;
	}
	
	/**
	 * 
	 *
	 */
	private void onUpdate() {

		float r = color.r;
		float g = color.g;
		float b = color.b;
		float a = color.a;

		r = toFloat(componentR.getText(), r);
		g = toFloat(componentG.getText(), g);
		b = toFloat(componentB.getText(), b);
		a = toFloat(componentA.getText(), a);

		color.set(r, g, b, a);
		
		if(callback != null)
			callback.componentModifiedCallback();
	}
	
	@Override
	public void setEnabled(boolean enabled)
	{
		super.setEnabled(enabled);
		
		componentR.setEnabled(enabled);
		componentG.setEnabled(enabled);
		componentB.setEnabled(enabled);
		componentA.setEnabled(enabled);
		
		rSlider.setEnabled(enabled);
		gSlider.setEnabled(enabled);
		bSlider.setEnabled(enabled);
		aSlider.setEnabled(enabled);
	}
}
